# 判断预测结节的中心点是否落在金标准结节所在的三维立体空间内
import imp
import math
import numpy as np
import cv2
from .compute_center import cal_c
from .cal_center_distance import cal_point_distance
from .cal_area import cal_area
from .log import logging
from .name_num_2_data import find_layer
# 将box转成polygan
def box_2_polygan(box):
    # 是box
    if len(np.shape(box))==1:
        polygan = [[box[0],box[1]],[box[2],box[1]],[box[2],box[3]],[box[0],box[3]]]
    # 是polygan
    else:
        polygan = box
    return polygan
# 判断一个点(point)是否落在另外一个轮廓(cnt)中
def center_drop_in_counter(point,cnt):
    # 点落在轮廓外界
    if(cv2.pointPolygonTest(contour = np.int0(cnt),pt = point,measureDist=False)<0):
        return 0
    # 点落在轮廓上或者轮廓内，都算命中
    else:
        return 1 
# 判断预测结节的中心点是否落在金标准结节所在的三维立体空间内
def drop_in(set_gt,gt_layer,set_ai,ai_layer,thickness):
    # drop_flag 为1.0时候说明掉入
    # drop_flag 为0.0时候说明没有掉入
    drop_flag = 0.0
    max_area_ai = 0
    max_area_gt = 0
    for i in range(len(set_ai)):
        box_or_polygan_ai = set_ai[i]
        cnt = np.int0(box_2_polygan(box=box_or_polygan_ai))
        area_ai = cal_area(cnt)
        # 找出不同层的预测结节中的最大面积层号以及该层的中心点
        if(max_area_ai < area_ai):
            max_area_ai = area_ai
            center_ai= cal_c(cnt)
            max_area_ai_layer = ai_layer[i]

    for i in range(len(set_gt)):
        cnt = np.int0(box_2_polygan(box=set_gt[i]))
        area_gt = cal_area(cnt)
        # 找出不同层的预测结节中的最大面积层号以及该层的中心点
        if(max_area_gt < area_gt):
            max_area_gt = area_gt
            center_gt_new= cal_c(cnt)
            max_area_gt_layer = gt_layer[i]

    # 判断金标准标注是否有手工边界 0表示没有，1表示有
    polygan_flag = 0            
    for i in range(len(set_gt)):
        # 判断预测结节中的最大面积层中心点是否落入同层的金标准box中
        if(gt_layer[i] == max_area_ai_layer):
            # 当前层的box或者多边形标注，先处理多边形，多边形优先级高
            if(len(np.shape(box_or_polygan_ai))==2):
                box_or_polygan_gt = set_gt[i]
                polygan_flag = 1
                # drop_flag 为1.0时候说明掉入
                drop_flag = center_drop_in_counter(center_ai,box_or_polygan_gt)
    # 如果没有手工边界，只有bbox，那就用bbox
    if(polygan_flag == 0):
        for i in range(len(set_gt)):
            # 判断预测结节中的最大面积层中心点是否落入同层的金标准box中
            if(gt_layer[i] == max_area_ai_layer):
                # 如果没有手工边界，只有bbox，那就用bbox
                if(len(np.shape(box_or_polygan_ai))==1):
                    box_or_polygan_gt = set_gt[i]
                    polygan_flag = 1
                    # drop_flag 为1.0时候说明掉入
                    drop_flag = center_drop_in_counter(center_ai,box_2_polygan(box_or_polygan_gt))
    center_point_dis = cal_point_distance(center_ai,center_gt_new,thickness*abs(max_area_gt_layer-max_area_ai_layer))
    return drop_flag,center_point_dis